package com.water.auth.security;

import java.util.List;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.oauth2.server.authorization.config.annotation.web.configurers.OAuth2AuthorizationServerConfigurer;
import org.springframework.security.oauth2.server.authorization.web.authentication.OAuth2TokenRevocationAuthenticationConverter;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;

@Configuration
@EnableWebSecurity
public class SecurityConfig {
//	@Bean
//	public UserDetailsService userDetailsService(DataSource dataSource) {
//	    return new JdbcUserDetailsManager(dataSource);
//	}

	// DaoAuthenticationProvider 负责用户认证。
	// setUserDetailsService(userDetailsService) 绑定用户数据源。
	// setPasswordEncoder(new BCryptPasswordEncoder()) 设置密码加密方式。
	// ProviderManager 作为 AuthenticationManager 的实现。
	@Bean
	public AuthenticationManager authenticationManager(UserDetailsService userDetailsService) throws Exception {
	    DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
	    authProvider.setUserDetailsService(userDetailsService);
	    // authProvider.setPasswordEncoder(new BCryptPasswordEncoder());
	    authProvider.setPasswordEncoder(new PlainTextPasswordEncoder());

	    return new ProviderManager(authProvider);
	}
    
	@Bean
	@Order(1)
	public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
		OAuth2AuthorizationServerConfigurer authorizationServerConfigurer = OAuth2AuthorizationServerConfigurer
				.authorizationServer();
		http.cors(cors -> cors.configurationSource(corsConfigurationSource()));
		// http.csrf(csrf -> csrf.disable()); // ✅ 替代旧的csrf()
		// 仅作用于OAuth2相关端点
		http.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher());
		// 开启OIDC支持
		http.with(authorizationServerConfigurer,
				authorizationServer -> authorizationServer.oidc(Customizer.withDefaults()));
		// 允许所有OAuth2相关请求，其他API需认证
		http.authorizeHttpRequests(
				auth -> auth.requestMatchers(HttpMethod.OPTIONS).permitAll().anyRequest().authenticated());
		http.exceptionHandling(exception -> exception.authenticationEntryPoint(
				// 未认证时的处理
				new LoginUrlAuthenticationEntryPoint("/login")));
//		http.exceptionHandling(exception -> exception
//	            .authenticationEntryPoint(
//	                new CustomAuthenticationEntryPoint()
//	            ) .accessDeniedHandler(
//	                    // 已认证但权限不足时的处理
//	                    new AccessDeniedHandlerImpl();
//	                )
//	        );
		http.csrf(csrfConfigurer -> {
			csrfConfigurer.ignoringRequestMatchers("/oauth2/revoke");
		});
		OAuth2TokenRevocationAuthenticationConverter a;
		return http.build();
	}

	// @Bean
	public CorsConfigurationSource corsConfigurationSource() {
		// ✅ 正确启用 CORS，替代 http.cors()
		// ✅ 支持跨域请求，允许 Authorization 头透传
		// ✅ 使用 CorsConfigurationSource 进行细粒度 CORS 配置
		CorsConfiguration configuration = new CorsConfiguration();
		configuration.setAllowedOrigins(List.of("http://apigateway"));
		configuration.setAllowedMethods(List.of("GET", "POST", "OPTIONS"));
		configuration.setAllowedHeaders(List.of("x-csrf-token", "Authorization", "Content-Type", "X-Requested-With"));
		configuration.setAllowCredentials(false);

		UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
		source.registerCorsConfiguration("/**", configuration);
		return source;
	}

	@Bean
	@Order(2)
	public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
		http.cors(cors -> cors.configurationSource(corsConfigurationSource()));
		// http.csrf(csrf -> csrf.disable()); // ✅ 替代旧的 csrf()
		http.authorizeHttpRequests(
				auth -> auth.requestMatchers("/login", "/logout").permitAll().anyRequest().authenticated());
		// http.formLogin(Customizer.withDefaults());// formLogin不能disable csrf
		http.formLogin(configurer -> configurer.loginPage("/login").permitAll()); // 登录页面定制
		http.exceptionHandling(
				exception -> exception.authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/login")));
		http.logout(logout -> logout.logoutUrl("/logout") // ✅ 认证服务器处理`logout`:仅处理会话登出，但不会自动清除OAuth2
															// Token,如要清除，需在logoutSuccessHandler或logoutSuccessHandler中处理
				.addLogoutHandler((request, response, authentication) -> {
					System.out.println("===>logout");
					SecurityContextHolder.clearContext(); // 清除用户认证信息
					request.getSession().invalidate(); // 清除 session
				})
//                .logoutSuccessHandler((request, response, authentication) -> {
//                	SecurityContextHolder.clearContext(); // 清理认证信息
//                    response.sendRedirect("/login");
//                })
				.logoutSuccessUrl("/login") // ✅ 退出后跳转到登录页
				.invalidateHttpSession(true) // ✅ 清除会话
				.deleteCookies("JSESSIONID") // ✅ 删除Cookie
		);
		// http.csrf(csrf ->
		// csrf.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())); //
		// ✅ 存储CSRF令牌
		http.csrf(csrfConfigurer -> {
			csrfConfigurer.ignoringRequestMatchers("/oauth2/revoke");
		});
		return http.build();
	}

	/**
	 * ✅ RegisteredClientRepository 定义 OAuth2 客户端注册信息 ✅ clientId 和 clientSecret
	 * 用于客户端认证 ✅ 支持 authorization_code 授权模式 ✅ 启用了 openid、profile、email 范围，支持 OIDC 认证
	 * ✅ 使用 InMemoryRegisteredClientRepository 存储 Client 信息（生产环境建议存入数据库）
	 * 
	 * @return RegisteredClientRepository
	 */
//    @Bean
//    public RegisteredClientRepository registeredClientRepository() {
//        RegisteredClient gateway = RegisteredClient.withId(UUID.randomUUID().toString())
//            .clientId("apigateway")
//            .clientSecret("{noop}apigateway-secret") // NoOp 表示未加密存储
//            .authorizationGrantTypes(grants -> grants.add(AuthorizationGrantType.AUTHORIZATION_CODE))
//            .redirectUri("http://apigateway/login/oauth2/code/apigateway") // 客户端回调地址
//            .scopes(scopes -> {scopes.add("openid");scopes.add("profile");scopes.add("email");})
//            .clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
//            .build();
//        
//        RegisteredClient expertextractionservice = RegisteredClient.withId(UUID.randomUUID().toString())
//                .clientId("expertextractionservice")
//                .clientSecret("{noop}expertextractionservice-secret") // NoOp 表示未加密存储
//                .authorizationGrantTypes(grants -> grants.add(AuthorizationGrantType.AUTHORIZATION_CODE))
//                .redirectUri("http://expertextractionservice:9090/expertextractionservice/login/oauth2/code/expertextractionservice") // 客户端回调地址
//                .scopes(scopes -> {scopes.add("openid");scopes.add("profile");scopes.add("email");})
//                .clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
//                .build();
//        
//        RegisteredClient systemmanagerservice = RegisteredClient.withId(UUID.randomUUID().toString())
//                .clientId("systemmanagerservice")
//                .clientSecret("{noop}systemmanagerservice-secret") // NoOp 表示未加密存储
//                .authorizationGrantTypes(grants -> grants.add(AuthorizationGrantType.AUTHORIZATION_CODE))
//                .redirectUri("http://systemmanagerservice:9099/systemmanagerservice/login/oauth2/code/systemmanagerservice") // 客户端回调地址
//                .scopes(scopes -> {scopes.add("openid");scopes.add("profile");scopes.add("email");})
//                .clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
//                .build();
//
//        return new InMemoryRegisteredClientRepository(gateway,expertextractionservice,systemmanagerservice);
//    }

//	@Bean
//	public FilterRegistrationBean<CorsFilter> corsFilter() {
//		UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
//		CorsConfiguration config = new CorsConfiguration();
//		config.setAllowedOrigins(List.of("http://apigateway")); // 允许的前端 URL
//		config.setAllowedMethods(List.of("GET", "POST", "OPTIONS")); // 允许的 HTTP 方法
//		config.setAllowedHeaders(List.of("Authorization", "Content-Type"));
//		config.setAllowCredentials(false); // 允许Cookie
//		source.registerCorsConfiguration("/**", config);
//		return new FilterRegistrationBean<>(new CorsFilter(source));
//	}

}